package ecustom.clients.util;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import ecustom.common.AbstractBaseAction;
import ecustom.common.conn.DB;
import ecustom.common.util.CustomUtil;
import weaver.file.Prop;
import weaver.interfaces.workflow.action.Action;
import weaver.soa.workflow.request.Cell;
import weaver.soa.workflow.request.Property;
import weaver.soa.workflow.request.RequestInfo;
import weaver.soa.workflow.request.Row;

public abstract class AbstractAction extends AbstractBaseAction implements Action {

	private String operate;

	@Override
	public String execute(RequestInfo requestInfo) {
		int requestId = requestInfo.getRequestManager().getRequestid();
		long time = System.currentTimeMillis();
		log().info(this.getClass().getName() + " Start, requestId = " + requestId);
		Map<String, Object> log = new HashMap<String, Object>();
		log.put("reqId", requestId);
		log.put("actionClass", this.getClass().getName());
		log.put("startTime", CustomUtil.getStringDate("yyyy-MM-dd HH:mm:ss.SSS"));
		log.put("operatorId", requestInfo.getRequestManager().getUser().getUID());
		log.put("src", requestInfo.getRequestManager().getSrc());
		try {
			log.put("requestMark", DB.conn().getString("SELECT REQUESTMARK FROM WORKFLOW_REQUESTBASE WHERE REQUESTID=?", requestId));
			log.put("ip", CustomUtil.getLocalIP());
			process(requestInfo);
			log.put("status", 1);
			log.put("message", "自定义接口执行成功！");
			return Action.SUCCESS;
		} catch (Exception e) {
			log.put("status", 0);
			log.put("message", e.toString());
			logError(requestInfo, e);
		} catch(Error e) {
			log.put("status", 0);
			log.put("message", e.toString());
			logError(requestInfo, e);
		} catch(Throwable e) {
			log.put("status", 0);
			log.put("message", e.toString());
			logError(requestInfo, e);
		} finally {
			log.put("seconds", (System.currentTimeMillis() - time) / 1000.0);
			log.put("endTime", CustomUtil.getStringDate("yyyy-MM-dd HH:mm:ss.SSS"));
			saveActionLog(log);
			log().info(this.getClass().getName() + " End, requestId = " + requestId + ", ms: " + (System.currentTimeMillis() - time));
		}
		
		return Action.FAILURE_AND_CONTINUE;
	}
	
	public abstract void process(RequestInfo requestInfo) throws Exception;
	
	public String getOperate() {
		return operate;
	}

	public void setOperate(String operate) {
		this.operate = operate;
	}
	
	/**
	 * 获取主表数据，并转换成Integer类型值返回。
	 * @param fields
	 * @param fieldName
	 * @return
	 */
	public static Integer getMainIntegerValue(Property[] fields, String fieldName) {
		return getMainIntegerValue(fields, fieldName, null);
	}

	/**
	 * 获取主表数据，并转换成Integer类型值返回。
	 * @param fields
	 * @param fieldName
	 * @param defValue
	 * @return
	 */
	public static Integer getMainIntegerValue(Property[] fields, String fieldName, Integer defValue) {
		String value = null;
		for (Property field : fields) {
			if (fieldName.equalsIgnoreCase(field.getName())) {
				value = field.getValue();
				break ;
			}
		}
		return CustomUtil.getInteger(value, defValue);
	}
	
	/**
	 * 获取主表数据，并转换成Double类型值返回。
	 * @param fields
	 * @param fieldName
	 * @param errMsg
	 * @return
	 */
	public static Double getMainDoubleCK(Property[] fields, String fieldName, String errMsg) {
		Double value = getMainDoubleValue(fields, fieldName);
		if (value == null) throw new RuntimeException(errMsg);
		return value;
	}
	
	/**
	 * 获取主表数据，并转换成Double类型值返回。
	 * @param fields
	 * @param fieldName
	 * @return
	 */
	public static Double getMainDoubleValue(Property[] fields, String fieldName) {
		return getMainDoubleValue(fields, fieldName, null);
	}

	/**
	 * 获取主表数据，并转换成Double类型值返回。
	 * @param fields
	 * @param fieldName
	 * @param defValue
	 * @return
	 */
	public static Double getMainDoubleValue(Property[] fields, String fieldName, Double defValue) {
		String value = null;
		for (Property field : fields) {
			if (fieldName.equalsIgnoreCase(field.getName())) {
				value = field.getValue();
				break ;
			}
		}
		return CustomUtil.getDouble(value, defValue);
	}
	
	/**
	 * 获取主表数据，并转换成String类型值返回。
	 * @param fields
	 * @param fieldName
	 * @return
	 */
	public static String getMainString(Property[] fields, String fieldName) {
		return getMainStringValue(fields, fieldName, null);
	}
	
	public static String getMainStringCK(Property[] fields, String fieldName, String errMsg) {
		String value = getMainStringValue(fields, fieldName, null);
		if (CustomUtil.isBlank(value)) throw new RuntimeException(errMsg);
		return value;
	}
	
	/**
	 * 	获取主表数据，并转换成String类型值返回。
	 * @param fields
	 * @param fieldName
	 * @return
	 */
	public static String getMainStringValue(Property[] fields, String fieldName) {
		return getMainStringValue(fields, fieldName, null);
	}
	
	/**
	 * 获取主表数据，并转换成String类型值返回。
	 * @param fields
	 * @param fieldName
	 * @param defValue
	 * @return
	 */
	public static String getMainStringValue(Property[] fields, String fieldName, String defValue) {
		String value = null;
		for (Property field : fields) {
			if (fieldName.equalsIgnoreCase(field.getName())) {
				value = field.getValue();
				break ;
			}
		}
		return CustomUtil.isBlank(value) ? defValue : value;
	}
	
	public static String getCellStringValue(Row row, String fieldName) {
		return getCellStringValue(row, fieldName, "");
	}
	
	public String getCellStringValueCK(Row row, String fieldName, String errMsg) {
		return getCellStringCK(row, fieldName, errMsg);
	}
	
	/**
	 * 获取创建日期。
	 * @param requestInfo
	 * @return
	 * @throws SQLException
	 * Create date: Feb 21, 2021
	 */
	public String getCreateDate(RequestInfo requestInfo) throws Exception {
		String createDate = requestInfo.getRequestManager().getCreatedate();
		if (CustomUtil.isBlank(createDate)) {
			initRequestManager(requestInfo);
		}
		return requestInfo.getRequestManager().getCreatedate();
	}

	/**
	 * 获取明细表数据，并转换成String类型值返回。
	 * @param rows
	 * @param fieldName
	 * @param defValue
	 * @return
	 */
	public static String getCellStringValue(Row row, String fieldName, String defValue) {
		if (CustomUtil.isBlank(fieldName)) return "";
		String value = null;
		Cell[] cells = row.getCell();
		for (Cell field : cells) {
			if (fieldName.equalsIgnoreCase(field.getName())) {
				value = field.getValue();
				break ;
			}
		}
		return CustomUtil.isBlank(value) ? defValue : value;
	}
	
	public static String getCellStringValueCK(RequestInfo requestInfo, String fieldName, String errMsg) throws Exception {
		String value = getCellStringValueCK(requestInfo, 0, fieldName, errMsg);
		if (CustomUtil.isBlank(value)) throw new RuntimeException(errMsg);
		return value;
	}
	
	public static String getCellStringValueCK(RequestInfo requestInfo, int detailIndex, String fieldName, String errMsg) throws Exception {
		String value = getCellStringValueCK(requestInfo, detailIndex, 0, fieldName, errMsg);
		if (CustomUtil.isBlank(value)) throw new RuntimeException(errMsg);
		return value;
	}
	
	public static String getCellStringValueCK(RequestInfo requestInfo, int detailIndex, int rowIndex, String fieldName, String errMsg) throws Exception {
		String value = getCellStringValue(requestInfo, detailIndex, 0, fieldName);
		if (CustomUtil.isBlank(value)) throw new RuntimeException(errMsg);
		return value;
	}

	public static String getCellStringValue(RequestInfo requestInfo, int detailIndex, int rowIndex, String fieldName) throws Exception {
		Row[] rows = AbstractAction.getRows(requestInfo, detailIndex);
		if (rows == null || rows.length <= 0) return "";
		return AbstractAction.getCellStringValue(rows[rowIndex], fieldName);
	}
	
	public static int getCellIntCK(Row row, String fieldName, String errMsg) {
		Integer value = getCellIntegerValue(row, fieldName, null);
		if (value == null) throw new RuntimeException(errMsg);
		return value;
	}
	
	public static Integer getCellInteger(Row row, String fieldName) {
		return getCellIntegerValue(row, fieldName, null);
	}
	
	/**
	 * 获取明细表数据，并转换成Integer类型值返回。
	 * @param rows
	 * @param fieldName
	 * @param defValue
	 * @return
	 */
	public static Integer getCellIntegerValue(Row row, String fieldName, Integer defValue) {
		if (CustomUtil.isBlank(fieldName)) return null;
		String value = null;
		Cell[] cells = row.getCell();
		for (Cell field : cells) {
			if (fieldName.equalsIgnoreCase(field.getName())) {
				value = field.getValue();
				break ;
			}
		}
		return CustomUtil.getInteger(value, defValue);
	}
	
	public static Double getCellDoubleCK(Row row, String fieldName, String errMsg) {
		Double value = getCellDoubleValue(row, fieldName);
		if (value == null) throw new RuntimeException(errMsg);
		return value;
	}
	
	public static Double getCellDoubleValue(Row row, String fieldName) {
		if (CustomUtil.isBlank(fieldName)) return null;
		String value = null;
		Cell[] cells = row.getCell();
		for (Cell field : cells) {
			if (fieldName.equalsIgnoreCase(field.getName())) {
				value = field.getValue();
				break ;
			}
		}
		return CustomUtil.getDouble(value, null);
	}

	public static Integer getMainInteger(Property[] fields, String fieldName) {
		return getMainIntegerValue(fields, fieldName, null);
	}
	
	public static Integer getMainIntegerCK(Property[] fields, String fieldName, String errMsg) {
		Integer value = getMainIntegerValue(fields, fieldName, null);
		if (value == null) throw new RuntimeException(errMsg);
		return value;
	}
	
	/**
	 * 获取指定明细表中的所有行。
	 * @param requestInfo
	 * @param detailIndex	明细表索引，下标从1开始。
	 * @return
	 * Create date: 2020年8月13日
	 */
	public static Row[] getRows(RequestInfo requestInfo, int detailIndex) {
		return requestInfo.getDetailTableInfo().getDetailTable(detailIndex - 1).getRow();
	}
	
	/**
	 * 获取指定明细表中的所有行。
	 * @param requestInfo
	 * @param detailIndex	明细表索引，下标从1开始。
	 * @param errMsg	异常消息文本，如果没有获取到明细行则抛出异常
	 * @return
	 * Create date: 2020年8月13日
	 */
	public static Row[] getRowsCK(RequestInfo requestInfo, int detailIndex, String errMsg) {
		Row[] rows = getRows(requestInfo, detailIndex);
		if (rows == null || rows.length == 0) throw new RuntimeException(errMsg);
		return rows;
	}
	
	private void initRequestManager(RequestInfo requestInfo) throws Exception {
		int requestId = CustomUtil.getInt(requestInfo.getRequestid());
		Map<String, Object> map = DB.conn().one("SELECT * FROM WORKFLOW_REQUESTBASE WHERE REQUESTID=?", requestId);
		requestInfo.getRequestManager().setCreatedate(map.get("CREATEDATE").toString());
		requestInfo.getRequestManager().setCreatetime(map.get("CREATETIME").toString());
	}
	
	private void logError(RequestInfo requestInfo, Throwable e) {
		int requestId = requestInfo.getRequestManager().getRequestid();
		String msg = "<div style=\"padding-bottom: 10px;\">报错时间：" + CustomUtil.getStringDate("yyyy-MM-dd HH:mm:ss")
				+ "， 请求ID：" + requestId + "，文件：" + getClass().getName() + "</div>"
				+ "<span>提示消息：" + e.getMessage() + "</span>";
		log().error(msg, e);
		requestInfo.getRequestManager().setMessageid("20088");
		requestInfo.getRequestManager().setMessagecontent(msg);
	}

	private void saveActionLog(Map<String, Object> log) {
		String table = Prop.getPropValue("ecustom", "action.log.table");
		if (CustomUtil.isBlank(table)) {
			log().debug(log);
			return ;
		}
		
		try {
			DB.conn().save(table, log);
		} catch (Exception e) {
			log().error("保存自定义接口执行日志失败", e);
		}
	}
}